package com.koron.ticket.work.common.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.koron.bean.base.Response;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.business.datadict.utils.DataDictTool;
import com.koron.common.core.business.workflow.bean.properties.WorkflowProperties;
import com.koron.common.core.business.workflow.templates.WorkFlowHandler;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CodeTools;
import com.koron.ticket.work.common.bean.TicketBaseMsg;
import com.koron.ticket.work.enums.TicketStatus;
import com.koron.ticket.work.logicticket.hightask.bean.YcHightaskTicketPrint;
import com.koron.ticket.work.securityarrangement.bean.SecurityArrangement;
import com.koron.ticket.work.securityarrangement.service.SecurityArrangementService;
import com.koron.ticket.work.workPermit.bean.WorkPermit;
import com.koron.ticket.work.workflow.bean.WorkFlow;
import com.koron.ticket.work.workflow.service.WorkFlowService;
import com.koron.ticket.work.worklocation.bean.WorkLocationBean;
import com.koron.ticket.work.worklocation.service.WorkLocationService;
import com.koron.ticket.work.workmember.bean.WorkMember;
import com.koron.ticket.work.workmember.service.WorkMemberService;
import com.koron.ticket.work.workteam.bean.WorkTeam;
import com.koron.ticket.work.workteam.service.WorkTeamService;
import com.koron.ticket.work.workticket.bean.WorkTicket;
import com.koron.ticket.work.workticket.mapper.WorkTicketMapper;
import com.koron.ticket.work.workticket.service.WorkTicketService;
import com.koron.ticket.work.workycinfo.bean.TicketYcInfoBean;
import com.koron.ticket.work.workycinfo.service.WorkYcInfoService;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 工作票工作业务集中处理服务
 */
@Service
public class YcCommonService {

    private EamUser getCurrUser() {
        return ThreadLocalContext.get();
    }

    @Autowired
    private WorkYcInfoService workycinfoservice;

    @Autowired
    private SecurityArrangementService securityArrangementService;

    @Autowired
    private WorkTicketService workTicketService;

    @Autowired
    private WorkTeamService workTeamService;

    @Autowired
    private WorkMemberService workMemberService;

    @Autowired
    private WorkLocationService worklocationservice;

    @Autowired
    private WorkFlowHandler workFlowHandler;

    @Autowired
    private WorkFlowService workFlowService;


    /**
     * 更新基础信息
     *
     * @param factory
     * @param ticketId
     * @param ticketbasemsg
     */
    public void updateTicketMsg(SessionFactory factory, String ticketId, TicketBaseMsg ticketbasemsg) {
        List<WorkLocationBean> workLocationList = ticketbasemsg.getWorkLocationList();
        List<WorkTeam> workTeamList = ticketbasemsg.getWorkTeamList();
        List<WorkMember> workMemberList = ticketbasemsg.getWorkMemberList();
        List<SecurityArrangement> securityArrangementList = ticketbasemsg.getSecurityArrangementList();


        // 工作地点
        if (CollUtil.isNotEmpty(workLocationList)) {
            worklocationservice.deleteByWorkTicketId(factory, ticketId);
            worklocationservice.batchInsertOnTicketId(factory, workLocationList, ticketId);
        }

        // 工作班组
        if (CollUtil.isNotEmpty(workTeamList)) {
            workTeamService.deleteByWorkTicketId(factory, ticketId);
            workTeamService.batchInsertOnTicketId(factory, workTeamList, ticketId);
        }

        // 工作班组成员
        if (CollUtil.isNotEmpty(workMemberList)) {
            workMemberService.deleteByWorkTicketId(factory, ticketId);
            workMemberService.batchInsertOnTicketId(factory, workMemberList, ticketId);
        }

        //安全措施
        if (CollUtil.isNotEmpty(securityArrangementList)) {
            securityArrangementService.deleteByWorkTicketId(factory, ticketId);
            Stream.iterate(0, i->i+1).limit(securityArrangementList.size()).forEach(s->{
                SecurityArrangement securityArrangement = securityArrangementList.get(s);
                securityArrangement.setSort(s+1);
            });
            securityArrangementService.batchInsertOnTicketId(factory, securityArrangementList, ticketId);
        }

        return;
    }

    /**
     * 查询工作票基础信息
     *
     * @param factory
     * @param ticketId
     * @return
     */
    public TicketBaseMsg queryTicketMsg(SessionFactory factory, String ticketId) {
        TicketBaseMsg ticketBaseMsg = new TicketBaseMsg();

        List<WorkLocationBean> worklocationlist = worklocationservice.getList(factory, ticketId);
        List<WorkTeam> workTeamlist = workTeamService.queryById(factory, ticketId);
        List<WorkMember> workMemberlist = workMemberService.queryByWorkTicketId(factory, ticketId);
        List<SecurityArrangement> securityArrangementlist = securityArrangementService.queryByWorkTicketId(factory, ticketId);

        if (CollUtil.isNotEmpty(worklocationlist)) {
            ticketBaseMsg.setWorkLocationList(worklocationlist);
        }

        // 工作班组
        if (CollUtil.isNotEmpty(workTeamlist)) {
            ticketBaseMsg.setWorkTeamList(workTeamlist);
        }

        // 工作班组成员
        if (CollUtil.isNotEmpty(workMemberlist)) {
            ticketBaseMsg.setWorkMemberList(workMemberlist);
        }

        //安全措施
        if (CollUtil.isNotEmpty(securityArrangementlist)) {
            ticketBaseMsg.setSecurityArrangementList(securityArrangementlist);
        }
        return ticketBaseMsg;
    }


    /**
     * 工作票-流程启动
     *
     * @param factory
     * @param workTicket
     * @param workFlowType
     * @return
     */
    public String ycWriteSubmitByWorkFlowType(SessionFactory factory, WorkTicket workTicket, String workFlowType) {
        String workTicketId = workTicket.getId();
        Map<String, String> form = new HashMap<>();
        form.put("user", getCurrUser().getAccount());

        workTicket.setStatus(TicketStatus.SIGN.getStatus());
        if (StrUtil.isEmpty(workTicketId)) {
            workTicketService.update(factory, workTicket);
        }
        // 2. 进入工作流
        WorkflowProperties wfp = WorkflowProperties.init(workFlowType);
        workFlowHandler.start(wfp, workTicketId, workTicket.getCode(), workTicket.getTitle(), form);
        // 3. 记录操作人
        WorkFlow workFlow = new WorkFlow();
        workFlow.setWorkTicketId(workTicketId);
        workFlow.setType("填写人");
        workFlow.setAccount(getCurrUser().getAccount());
        workFlow.setName(getCurrUser().getName());
        workFlow.setPhone(getCurrUser().getPhone());
        workFlow.setOperationTime(new Date());
        workFlow.setDeleteFlag(0);
        workFlowService.insert(factory, workFlow, TicketStatus.WRITE.getStatus());
        return workTicketId;
    }


    @TaskAnnotation("signSave")
    public Response signSave(SessionFactory factory, WorkFlow workFlow) {
        workTicketService.checkTimeOut(factory, workFlow.getWorkTicketId(), workFlow.getUpdateTime());//检查信息是否过期
        workFlowService.save(factory, workFlow);
        return Response.success("提交/保存成功");
    }

    @TaskAnnotation("countersignSave")
    public Response countersignSave(SessionFactory factory, WorkFlow workFlow) {
        workTicketService.checkTimeOut(factory, workFlow.getWorkTicketId(), workFlow.getUpdateTime());//检查信息是否过期
        workFlowService.save(factory, workFlow);
        return Response.success("提交/保存成功");
    }

    @TaskAnnotation("acceptSave")
    public Response acceptSave(SessionFactory factory, WorkFlow workFlow) {
        workTicketService.checkTimeOut(factory, workFlow.getWorkTicketId(), workFlow.getUpdateTime());//检查信息是否过期
        workFlowService.save(factory, workFlow);
        return Response.success("提交/保存成功");
    }

    @TaskAnnotation("permitSave")
    public Response permitSave(SessionFactory factory, WorkPermit workPermit) {
        workTicketService.checkTimeOut(factory, workPermit.getWorkTicketId(), workPermit.getUpdateTime());//检查信息是否过期
        String workTicketId = workPermit.getWorkTicketId();
        List<WorkFlow> workFlowList = workPermit.getWorkFlowList();
        // 3. 将工作票预览标志设置为未预览
        factory.getMapper(WorkTicketMapper.class).updatePreviewFlagById(1, workTicketId);
        // 许可可能有多个签名
        workFlowService.deleteByWorkTicketId(factory, workPermit.getWorkTicketId(), TicketStatus.PERMIT.getStatus());
        workFlowService.batchInsert(factory, workFlowList);
        return Response.success("待许可-提交/保存成功");
    }

    @TaskAnnotation("ticketEndSave")
    public Response ticketEndSave(SessionFactory factory, WorkFlow workFlow) {
        workTicketService.checkTimeOut(factory, workFlow.getWorkTicketId(), workFlow.getUpdateTime());//检查信息是否过期
        workFlowService.save(factory, workFlow);
        return Response.success("工作终结/工作票待终结-提交/保存成功");
    }


    /**
     * 高处作业票、动火安全作业票
     * 获取打印数据
     *
     * @param factory
     * @param ticketId
     * @return
     */
    @TaskAnnotation("getPrintData")
    public List<YcHightaskTicketPrint> getPrintData(SessionFactory factory, String ticketId) {
        List<YcHightaskTicketPrint> printlist = new ArrayList();

        // 作业类别字典
        Map<String, String> dataDictByCode = DataDictTool.getDataDictByCode("twoTicketManagement", "ticket_task_type");

        // 主表信息
        WorkTicket workTicket = workTicketService.queryById(factory, ticketId);
        // 信息
        TicketYcInfoBean ycInfo = workycinfoservice.getYcInfo(factory, ticketId);
        // 所有签名信息
        List<WorkFlow> workFlowlist = workFlowService.queryByTicketId(factory, ticketId);
        // 基础信息
        TicketBaseMsg ticketBaseMsg = queryTicketMsg(factory, ticketId);
        String locationStr = "";
        String workDeptStr = "";
        String memberNameListString = "";
        // 工作票状态
        Integer status = workTicket.getStatus();
        // 工作地点、作业地点
        if (CollUtil.isNotEmpty(ticketBaseMsg.getWorkLocationList())) {
            locationStr = ticketBaseMsg.getWorkLocationList().stream().map(WorkLocationBean::getLocationName).collect(Collectors.joining(","));
        }
        // 工作班组、作业单位
        if (CollUtil.isNotEmpty(ticketBaseMsg.getWorkTeamList())) {
            workDeptStr = ticketBaseMsg.getWorkTeamList().stream().map(WorkTeam::getWorkTeamName).collect(Collectors.joining(","));
        }
        // 工作班组成员、作业人
        if (CollUtil.isNotEmpty(ticketBaseMsg.getWorkMemberList())) {
            memberNameListString = ticketBaseMsg.getWorkMemberList().stream().map(WorkMember::getMemberName).collect(Collectors.joining(","));
        }
        Map<String, String> dictByClassCode = CodeTools.getDictByClassCode("operationManagement", "dispatch_type");


        YcHightaskTicketPrint ycticketprint = new YcHightaskTicketPrint();
        ycticketprint.setUnitName(workTicket.getUnitName());
        ycticketprint.setAppTime(DateUtil.format(ycInfo.getAppTime(), "yyyy年MM月dd日 HH时mm分"));
        ycticketprint.setCode(workTicket.getCode());
        ycticketprint.setLocationStr(locationStr);
        ycticketprint.setHeightWork(ycInfo.getHeightWork());
        ycticketprint.setJobCategoryStr(dataDictByCode.get(ycInfo.getJobCategory()));
        ycticketprint.setDirectorName(workTicket.getDirectorName());
        ycticketprint.setWorkDeptStr(workDeptStr);
//        ycticketprint.setNumber();
        ycticketprint.setGuardianName(ycInfo.getGuardianName());
        ycticketprint.setOtherSpecialWork(ycInfo.getOtherSpecialWork());
        ycticketprint.setOtherSpecialNum(ycInfo.getOtherSpecialNum());
        ycticketprint.setRiskResults(ycInfo.getRiskResults());
        ycticketprint.setSecurityName(ycInfo.getSecurityName());
        ycticketprint.setAcceptName(ycInfo.getAcceptName());
        ycticketprint.setMemberNameListString(memberNameListString);
        ycticketprint.setContent(workTicket.getContent());
        ycticketprint.setEstimatedStartTime(DateUtil.format(workTicket.getEstimatedStartTime(), "yyyy年MM月dd日 HH时mm分"));
        ycticketprint.setEstimatedEndTime(DateUtil.format(workTicket.getEstimatedEndTime(), "yyyy年MM月dd日 HH时mm分"));
        ycticketprint.setCreateName(workTicket.getCreateUserName());

        // 签发信息
        if (CollUtil.isNotEmpty(workFlowlist)) {
            if (status >= TicketStatus.SIGN.getStatus()) {
                Predicate<WorkFlow> predicateNode = f -> f.getStatus().equals(TicketStatus.SIGN.getStatus());//过滤节点
                Predicate<WorkFlow> predicateType = f -> f.getType().equals("name0");
                Optional<WorkFlow> first = workFlowlist.stream().filter(predicateNode.and(predicateType)).findFirst();
                Date sigTime = first.map(WorkFlow::getOperationTime).orElse(null);
                ycticketprint.setWorkUnitPerson(first.map(WorkFlow::getName).orElse(""));
                ycticketprint.setWorkUnitTime(DateUtil.format(sigTime, "yyyy年MM月dd日 HH时mm分"));
                ycticketprint.setWorkUnitMsg(first.map(WorkFlow::getOpinion).orElse(""));
            }
        }

        // 接收信息
        if (CollUtil.isNotEmpty(workFlowlist)) {
            if (status >= TicketStatus.ACCEPT.getStatus()) {
                Predicate<WorkFlow> predicateNode = f -> f.getStatus().equals(TicketStatus.ACCEPT.getStatus());//过滤节点
                Predicate<WorkFlow> predicateType = f -> f.getType().equals("name0");
                Optional<WorkFlow> first = workFlowlist.stream().filter(predicateNode.and(predicateType)).findFirst();
                Date sigTime = first.map(WorkFlow::getOperationTime).orElse(null);
                ycticketprint.setProduceSpacePerson(first.map(WorkFlow::getName).orElse(""));
                ycticketprint.setProduceSpaceTime(DateUtil.format(sigTime, "yyyy年MM月dd日 HH时mm分"));
                ycticketprint.setProduceSpaceMsg(first.map(WorkFlow::getOpinion).orElse(""));
            }
        }

        // 许可信息
        if (CollUtil.isNotEmpty(workFlowlist)) {
            if (status >= TicketStatus.PERMIT.getStatus()) {
                Predicate<WorkFlow> predicateNode = f -> f.getStatus().equals(TicketStatus.PERMIT.getStatus());//过滤节点
                Predicate<WorkFlow> predicateTypeOne = f -> f.getType().equals("name0");
                Predicate<WorkFlow> predicateTypeTwo = f -> f.getType().equals("name1");

                for (WorkFlow workFlow : workFlowlist) {
                    if (!workFlow.getStatus().equals(TicketStatus.PERMIT.getStatus())) {
                        continue;
                    }
                    if ("name0".equals(workFlow.getType())) {
                        ycticketprint.setAppCheckPerson(workFlow.getName());
                        ycticketprint.setAppCheckTime(DateUtil.format(workFlow.getOperationTime(), "yyyy年MM月dd日 HH时mm分"));
                        ycticketprint.setAppCheckMsg(workFlow.getOpinion());
                    }
                    if ("name1".equals(workFlow.getType())) {
                        ycticketprint.setApprovalPerson(workFlow.getName());
                        ycticketprint.setApprovalTime(DateUtil.format(workFlow.getOperationTime(), "yyyy年MM月dd日 HH时mm分"));
                        ycticketprint.setApprovalMsg(workFlow.getOpinion());
                    }
                }
            }
        }

        // 工作票结束信息
        if (CollUtil.isNotEmpty(workFlowlist)) {
            if (status >= TicketStatus.TICKET_END.getStatus()) {
                Predicate<WorkFlow> predicateNode = f -> f.getStatus().equals(TicketStatus.TICKET_END.getStatus());//过滤节点
                Predicate<WorkFlow> predicateType = f -> f.getType().equals("name0");
                Optional<WorkFlow> first = workFlowlist.stream().filter(predicateNode.and(predicateType)).findFirst();
                Date sigTime = first.map(WorkFlow::getOperationTime).orElse(null);
                ycticketprint.setCompletedPerson(first.map(WorkFlow::getName).orElse(""));
                ycticketprint.setCompletedTime(DateUtil.format(sigTime, "yyyy年MM月dd日 HH时mm分"));
                ycticketprint.setCompletedMsg(first.map(WorkFlow::getOpinion).orElse(""));
            }
        }

        // 安全措施
        for (SecurityArrangement securityArrangement : ticketBaseMsg.getSecurityArrangementList()) {
            YcHightaskTicketPrint securityPrint = new YcHightaskTicketPrint();
            BeanUtil.copyProperties(ycticketprint, securityPrint);
            securityPrint.setSecurityitem(securityArrangement.getItem());
            if (ObjectUtil.isNotNull(securityArrangement.getIsInvolve())) {
                Integer isInvolve = Integer.valueOf(securityArrangement.getIsInvolve());
                switch (isInvolve) {
                    case 1:
                        securityPrint.setSecurityIsInvolve("是");
                        break;
                    case 0:
                        securityPrint.setSecurityIsInvolve("否");
                        break;
                    default:
                        securityPrint.setSecurityIsInvolve("");
                        break;
                }
                securityPrint.setSecurityPerson(securityArrangement.getInvolveName());
            }
            printlist.add(securityPrint);
        }
        return printlist;
    }

}
